package cn.jiahui;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Arrays;

import com.jfinal.kit.JsonKit;
import com.mchange.v1.util.ArrayUtils;

public class LiftRWThread implements Runnable {
	Socket socket;
	String hostAddress = "";
	byte heatBeat[] = new byte[1];
	byte btnSateaData[] = new byte[9];
	byte listSateData[] = new byte[11];
	byte setSateData[] = new byte[10];

	BufferedInputStream bis = null;
	BufferedOutputStream bos = null;
	
	
	public LiftRWThread(Socket s) {
		super();
		
		this.socket = s;
		hostAddress = socket.getInetAddress().getHostAddress();
		Arrays.fill(heatBeat, (byte)0);
		Arrays.fill(btnSateaData, (byte)0);
		Arrays.fill(listSateData, (byte)0);
		Arrays.fill(setSateData, (byte)0);
		
		
		JsonKit j = new JsonKit();
		String ss = j.toJson(null);
		InputStream inputStream = null;
		OutputStream outputStream = null;
		try {
			inputStream = socket.getInputStream();
			outputStream = socket.getOutputStream();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		if (inputStream != null) {
			bis = new BufferedInputStream(inputStream);
		}
		if (outputStream != null) {
			bos = new BufferedOutputStream(outputStream);
		}

	}
	
	public String getBtnStateJson(){
		ArrayList<LiftBtnState> btnStateArry = new ArrayList<LiftBtnState>();
		//-2 是因为两个字节来判断类型了.
		LiftBtnState btn = new LiftBtnState();
		btn.btnId = 10;
		btn.name = "cop8";
		btn.light = (btnSateaData[10-2] & (byte)0X2) != 0 ? 1 : 0;
		btnStateArry.add(btn);
		
		btn = new LiftBtnState();
		btn.btnId = 9;
		btn.name = "cop7";
		btn.light = (btnSateaData[10-2] & (byte)0X1) != 0 ? 1 : 0;
		btnStateArry.add(btn);
		
		btn = new LiftBtnState();
		btn.btnId = 8;
		btn.name = "cop6";
		btn.light = (btnSateaData[9-2] & (byte)0X80) != 0 ? 1 : 0;
		btnStateArry.add(btn);
		
		btn = new LiftBtnState();
		btn.btnId = 7;
		btn.name = "cop5";
		btn.light = (btnSateaData[9-2] & (byte)0X40) != 0 ? 1 : 0;
		btnStateArry.add(btn);
		
		btn = new LiftBtnState();
		btn.btnId = 6;
		btn.name = "cop4";
		btn.light = (btnSateaData[9-2] & (byte)0X20) != 0 ? 1 : 0;
		btnStateArry.add(btn);
		
		btn = new LiftBtnState();
		btn.btnId = 5;
		btn.name = "cop3";
		btn.light = (btnSateaData[9-2] & (byte)0X10) != 0 ? 1 : 0;
		btnStateArry.add(btn);
		
		btn = new LiftBtnState();
		btn.btnId = 4;
		btn.name = "cop2";
		btn.light = (btnSateaData[9-2] & (byte)0X8) != 0 ? 1 : 0;
		btnStateArry.add(btn);
		
		btn = new LiftBtnState();
		btn.btnId = 3;
		btn.name = "cop1";
		btn.light = (btnSateaData[9-2] & (byte)0X4) != 0 ? 1 : 0;
		btnStateArry.add(btn);
		
		btn = new LiftBtnState();
		btn.btnId = 2;
		btn.name = "hib_down";
		btn.light = (btnSateaData[9-2] & (byte)0X2) != 0 ? 1 : 0;
		btnStateArry.add(btn);
		
		btn = new LiftBtnState();
		btn.btnId = 1;
		btn.name = "hib_up";
		btn.light = (btnSateaData[9-2] & (byte)0X1) != 0 ? 1 : 0;
		btnStateArry.add(btn);
		
		return JsonKit.toJson(btnStateArry);
	}

	@Override
	public void run() {
		try {
			
			if (bis != null) {

				byte[] head = new byte[2];
				while (true) {
					Arrays.fill(head, (byte) 0);
					int sizeHeadReaded = bis.read(head);
					if (sizeHeadReaded < 2) {
						System.out.println("head size < 2");
						break;
					} else {
						System.out.println("head:" + head[0] + " " + head[1]);
					}
					// 心跳包头,DTU send 心跳包是0x4A,0x48, 0x54, (ASCII : JHT), 间隔10s，
					if (head[0] == 0x4A && head[1] == 0x48) {
						readHeatBeat(bis);
						continue;
					}

					// 按钮的状态.DTU ask Data[10]
					if (head[0] == (byte) 0xA1 && head[1] == (byte) 0xA2) {
						boolean flag = readBtnState(bis);
						if (flag) {
							// TOOD 用另一个socket去读取真实电梯的数据.
						}
						// 把真实电梯的数据发到web
//						sendCommondReadBtnState(bos);
						continue;
					}

					// 电梯的状态.DTU ask Data[13]
					if (head[0] == (byte) 0xB1 && head[1] == (byte) 0xB2) {
						readLiftState(bis);
						continue;
					}

					// 设置命令 DTU ask Data[10]
					if (head[0] == (byte) 0x03 && head[1] == (byte) 0x6E) {
						// 和读取按钮的协议是一样的.
						readSetState(bis);
						
						continue;
					}

					// 退出命令
					// if(bs[0] == 'q' && bs[1] == 'u'){
					// StringBuilder sb = new StringBuilder();
					// String strWord = bis.readLine();
					// sb.append(bs[0]).append(bs[1])
					// .append(strWord);
					// if ("quit".equalsIgnoreCase(sb.toString())) {
					// System.out.println("quit");
					//
					// break;
					// }
					//
					// }

				}
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public boolean readHeatBeat(BufferedInputStream bis) throws IOException {
		int sizeToRead = 1;
		Arrays.fill(heatBeat, (byte)0);
		int beatSize = bis.read(heatBeat);
		if(beatSize == sizeToRead){
			System.out.println("beat bytes readed");
			HibUtils.printByte(heatBeat);
//			String result = HibUtils.doGet(prefixUrl+"hartBeat");
//			System.out.println( result);
			return true;
		}else{
			System.out.println("beat bytes readed failed");
		}
		return false;
	}

	public boolean readBtnState(BufferedInputStream bis) throws IOException {
		int sizeToRead = 9;
		Arrays.fill(btnSateaData, (byte) 0);
		int beatSize = bis.read(btnSateaData);
		if (beatSize == sizeToRead) {
			System.out.println("button state bytes readed");
			HibUtils.printByte(btnSateaData);
			// String result = HibUtils.doGet(prefixUrl+"socketAck/?result=ok");
			// System.out.println( result);
			return true;

		} else {
			System.out.println("button state bytes readed failed");
			// String result =
			// HibUtils.doGet(prefixUrl+"jiajing/socketAck/?result=failed");
			// System.out.println( result);
		}
		return false;
	}

	public boolean readLiftState(BufferedInputStream bis) throws IOException {
		int sizeToRead = 11;
		Arrays.fill(listSateData, (byte) 0);
		int beatSize = bis.read(listSateData);
		if (beatSize == sizeToRead) {
			System.out.println("lift state bytes readed");
			HibUtils.printByte(listSateData);
			return true;
		} else {
			System.out.println("lift state bytes readed failed");
		}
		return false;
	}

	public boolean readSetState(BufferedInputStream bis) throws IOException {
		int sizeToRead = 10;
		Arrays.fill(setSateData, (byte) 0);
		int beatSize = bis.read(setSateData);
		if (beatSize == sizeToRead) {
			System.out.println("set state bytes readed");
			HibUtils.printByte(setSateData);
			return true;
		} else {
			System.out.println("set state bytes readed failed");
		}
		return false;
	}

	public void writeLiftCommond( byte[] commond) throws IOException {
		bos.write(commond);
		bos.flush();
		HibUtils.printByte(commond);
		System.out.println("writeLiftCommond()");
	}

	public void writeCommondForLiftBtnState(byte[] btnState) throws IOException {
		// TODO 这些数据应该是从电梯那边读取来的.
		 btnState = new byte[]
		 {
			 (byte)0XA1, (byte)0XA2,
			 (byte)0X00, (byte)0X00,
			 (byte)0X00, (byte)0X06,
			 (byte)0X01, (byte)0X01,
			 (byte)0X00, (byte)0X01,
			 (byte)0X00, (byte)0X0A
		 };
		// 可以用上面的代码做下校验,看btnState是否正常.
		bos.write(btnState);
		bos.flush();
		System.out.println("sendCommondReadBtnState()");
	}

	public void writeCommondForLiftState(byte[] liftState) throws IOException {
		// TODO 这些数据应该是从电梯那边读取来的.
		liftState = new byte[]
		 {
		 (byte)0xB1, (byte)0xB2,
		 (byte)0x00, (byte)0x00,
		 (byte)0x00, (byte)0x06,
		 (byte)0x01, (byte)0x03,
		 (byte)0x00, (byte)0x06,
		 (byte)0x00, (byte)0x02
		 };
		bos.write(liftState);
		bos.flush();
		System.out.println("sendCommonForReadLiftState()");
	}

	public void writeCommondForSetBtnState(BufferedOutputStream bos, byte[] data,char btnCh) throws IOException {
		data = new byte[]
				{
						(byte)0x03, (byte)0x6E, 
						(byte)0x00, (byte)0x00, 
						(byte)0x00, (byte)0x06, 
						(byte)0x01, (byte)0x05, 
						(byte)0x00, (byte)0x00, 
						(byte)0xff, (byte)0xff
					};;
		if(btnCh == '1'){
			data[9] = 0x01;
		}
		if(btnCh == '2'){
			data[9] = 0x02;
		}
		if(btnCh == '3'){
			data[9] = 0x03;
		}
		if(btnCh == '4'){
			data[9] = 0x04;
		}
		if(btnCh == '5'){
			data[9] = 0x05;
		}
		if(btnCh == '6'){
			data[9] = 0x06;
		}
		if(btnCh == '7'){
			data[9] = 0x07;
		}
		if(btnCh == '8'){
			data[9] = 0x08;
		}
		if(btnCh == '9'){
			data[9] = 0x09;
		}
		if(btnCh == 'A'){
			data[9] = 0x0A;
		}
		bos.write(data);
		bos.flush();
		System.out.println("sendCommonForSetBtnState()");
	}

}
